home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1999 / MacHack 1999.toast / The Hacks / OutOfContextMenus / Source / COffscreenBehavior.cp < prev    next >
Encoding:
Text File  |  1999-06-25  |  20.2 KB  |  851 lines  |  [TEXT/CWIE]

  1. // ===========================================================================
  2. //    COffscreenBehavior.cp                 ©1999 Eric Traut
  3. // ===========================================================================
  4.  
  5. #include "COffscreenBehavior.h"
  6. #include "CShadowWindow.h"
  7. #include "COutOfContextApp.h"
  8.  
  9. #define UPDATE_WHEN_TRACKING        0
  10.  
  11.  
  12. Boolean            COffscreenBehavior::sOverrideQDProcsInited = false;
  13. CQDProcs        COffscreenBehavior::sOverrideQDProcs;
  14.  
  15. // ---------------------------------------------------------------------------
  16. //        • COffscreenBehavior
  17. // ---------------------------------------------------------------------------
  18.  
  19. COffscreenBehavior::COffscreenBehavior(
  20.     CShadowWindow &        inShadowWindow,
  21.     Boolean                inAllocateBacking,
  22.     Boolean                inDrawEveryTick)
  23.     :    CWindowBehavior(inShadowWindow)
  24. {
  25.     mBackingGWorld = NULL;
  26.     mRenderingGWorld = NULL;
  27.     mBackingChanged = false;
  28.     mGWorldsAllocated = false;
  29.     mAllocateBacking = inAllocateBacking;
  30.     mDrawEveryTick = inDrawEveryTick;
  31.     mLastBlitTicks = ::TickCount();
  32.  
  33.     if (!sOverrideQDProcsInited)
  34.         InitOverrideQDProcs();
  35.  
  36.     CWindowRecord *        colorWindow = inShadowWindow.GetMacWindow();
  37.     mOrigQDProcs = colorWindow->port.grafProcs;
  38.     mQDProcsOverridden = true;
  39.  
  40.     colorWindow->port.grafProcs = &sOverrideQDProcs;
  41.  
  42.     CWindowRecord *        macWindow = mShadowWindow.GetMacWindow();
  43.     Rect                entirePort = {-0x4000, -0x4000, 0x4000, 0x4000};
  44.     
  45.     ::SetPort(reinterpret_cast<GrafPtr>(macWindow));
  46.     
  47.     ::InvalRect(&entirePort);
  48.  
  49.     mFinderOffscreen = NULL;
  50. }
  51.  
  52.  
  53. // ---------------------------------------------------------------------------
  54. //        • ~COffscreenBehavior
  55. // ---------------------------------------------------------------------------
  56.  
  57. COffscreenBehavior::~COffscreenBehavior(void)
  58. {
  59.     DeleteGWorlds();
  60. }
  61.  
  62.  
  63. // ---------------------------------------------------------------------------
  64. //        • DeleteGWorlds
  65. // ---------------------------------------------------------------------------
  66.  
  67. void
  68. COffscreenBehavior::DeleteGWorlds(void)
  69. {
  70.     if (mRenderingGWorld != NULL)
  71.     {
  72.         ::DisposeGWorld(mRenderingGWorld);
  73.         mRenderingGWorld = NULL;
  74.     }
  75.  
  76.     if (mBackingGWorld != NULL)
  77.     {
  78.         ::DisposeGWorld(mBackingGWorld);
  79.         mBackingGWorld = NULL;
  80.     }
  81.     
  82.     mGWorldsAllocated = false;
  83. }
  84.  
  85.  
  86. // ---------------------------------------------------------------------------
  87. //        • SyncWithShadowWindow
  88. // ---------------------------------------------------------------------------
  89.  
  90. Boolean
  91. COffscreenBehavior::SyncWithShadowWindow(void)
  92. {
  93.     Boolean        neededChanged = false;
  94.     
  95.     if (!mGWorldsAllocated || GWorldNeedsSynching())
  96.     {
  97.         // In case one was allocated, delete them both
  98.         DeleteGWorlds();
  99.         
  100.         AllocateNewGWorlds();
  101.         neededChanged = true;
  102.     }
  103.     
  104.     return !neededChanged;
  105. }
  106.  
  107.  
  108. // ---------------------------------------------------------------------------
  109. //        • ShouldBlitAtIdleTime
  110. // ---------------------------------------------------------------------------
  111.  
  112. Boolean
  113. COffscreenBehavior::ShouldBlitAtIdleTime(void)
  114. {
  115.     if (!mGWorldsAllocated)
  116.         return false;
  117.     
  118.     if (DidOffscreenChange())
  119.         return true;
  120.  
  121.     if (mDrawEveryTick)
  122.     {
  123.         UInt32        curTickCount = ::TickCount();
  124.         
  125.         if (curTickCount != mLastBlitTicks)
  126.         {
  127.             mLastBlitTicks = curTickCount;
  128.             return true;
  129.         }
  130.     }
  131.     
  132.     return false;
  133. }
  134.  
  135.  
  136. // ---------------------------------------------------------------------------
  137. //        • DoIdleTask
  138. // ---------------------------------------------------------------------------
  139.  
  140. void
  141. COffscreenBehavior::DoIdleTask(
  142.     Boolean        inGNETime)
  143. {
  144.     #pragma unused (inGNETime)
  145.     
  146.     if (ShouldBlitAtIdleTime())
  147.     {
  148.         if (mAllocateBacking)
  149.         {
  150.             StGWorldLocker        backingLocker(mBackingGWorld, false);
  151.             StGWorldLocker        renderingLocker(mRenderingGWorld);
  152.  
  153.             if (RenderToGWorld(backingLocker, renderingLocker))
  154.                 CopyGWorldToScreen(renderingLocker);
  155.         }
  156.         else
  157.         {
  158.             StGWorldLocker        renderingLocker(mRenderingGWorld);
  159.             if (RenderToGWorld(renderingLocker))
  160.                 CopyGWorldToScreen(renderingLocker);
  161.         }
  162.     }
  163. }
  164.  
  165.  
  166. // ---------------------------------------------------------------------------
  167. //        • AllocateNewGWorlds
  168. // ---------------------------------------------------------------------------
  169.  
  170. void
  171. COffscreenBehavior::AllocateNewGWorlds(void)
  172. {
  173.     try
  174.     {
  175.         CWindowRecord *        colorWindow;
  176.         QDErr                err;
  177.         
  178.         Assert_(COutOfContextApp::GetAppHeap() == ::GetZone());
  179.         
  180.         // Allocate two new 16-bit GWorlds
  181.         colorWindow = mShadowWindow.GetMacWindow();
  182.         mGWorldRect = colorWindow->port.portRect;
  183.         ::OffsetRect(&mGWorldRect, -mGWorldRect.left, -mGWorldRect.top);
  184.         
  185.         if (mAllocateBacking)
  186.         {
  187.             err = ::NewGWorld(     &mBackingGWorld,
  188.                                 16,
  189.                                 &mGWorldRect,
  190.                                 NULL,
  191.                                 NULL,
  192.                                 0);
  193.             ThrowIfOSErr_(err);
  194.             ThrowIfNULL_(mBackingGWorld);
  195.         }
  196.  
  197.         err = ::NewGWorld(     &mRenderingGWorld,
  198.                             16,
  199.                             &mGWorldRect,
  200.                             NULL,
  201.                             NULL,
  202.                             0);
  203.         ThrowIfOSErr_(err);
  204.         ThrowIfNULL_(mRenderingGWorld);
  205.  
  206.         mGWorldsAllocated = true;
  207.         EraseGWorldBackgrounds();
  208.     }
  209.     catch (...)
  210.     {
  211.         DeleteGWorlds();
  212.     }
  213. }
  214.  
  215.  
  216. // ---------------------------------------------------------------------------
  217. //        • GWorldNeedsSynching
  218. // ---------------------------------------------------------------------------
  219.  
  220. Boolean
  221. COffscreenBehavior::GWorldNeedsSynching(void)
  222. {
  223.     Rect                newRect;
  224.  
  225.     CWindowRecord *        colorWindow;
  226.  
  227.     colorWindow = mShadowWindow.GetMacWindow();
  228.     newRect = colorWindow->port.portRect;
  229.     ::OffsetRect(&newRect, -newRect.left, -newRect.top);
  230.  
  231.     if (newRect.right != mGWorldRect.right || 
  232.         newRect.bottom != mGWorldRect.bottom)
  233.     {
  234.         return true;
  235.     }
  236.     
  237.     return false;
  238. }
  239.  
  240.  
  241. // ---------------------------------------------------------------------------
  242. //        • EraseGWorldBackgrounds
  243. // ---------------------------------------------------------------------------
  244.  
  245. void
  246. COffscreenBehavior::EraseGWorldBackgrounds(void)
  247. {
  248.     if (mAllocateBacking)
  249.     {
  250.         StGWorldLocker        locker(mBackingGWorld);
  251.         
  252.         ::BackColor(whiteColor);
  253.         ::EraseRect(&mGWorldRect);
  254.     }
  255.  
  256.     {
  257.         StGWorldLocker        locker(mRenderingGWorld);
  258.         
  259.         ::BackColor(whiteColor);
  260.         ::EraseRect(&mGWorldRect);
  261.     }
  262. }
  263.  
  264.  
  265. // ---------------------------------------------------------------------------
  266. //        • RenderToGWorld
  267. // ---------------------------------------------------------------------------
  268.  
  269. Boolean
  270. COffscreenBehavior::RenderToGWorld(
  271.     StGWorldLocker &        inBackingLocker,
  272.     StGWorldLocker &        inRenderingLocker)
  273. {
  274.     // Subclasses should override. By default, we'll
  275.     // just copy the contents of the backing offscreen.
  276.  
  277.     ::CopyBits(    reinterpret_cast<BitMap *>(*inBackingLocker.GetPixMap()),
  278.                 reinterpret_cast<BitMap *>(*inRenderingLocker.GetPixMap()),
  279.                 &mGWorldRect,
  280.                 &mGWorldRect,
  281.                 srcCopy,
  282.                 NULL);
  283.  
  284.     return true;
  285. }
  286.  
  287.  
  288. // ---------------------------------------------------------------------------
  289. //        • RenderToGWorld
  290. // ---------------------------------------------------------------------------
  291.  
  292. Boolean
  293. COffscreenBehavior::RenderToGWorld(
  294.     StGWorldLocker &        inRenderingLocker)
  295. {
  296.     #pragma unused (inRenderingLocker)
  297.     
  298.     // Subclasses should override.
  299.     return true;
  300. }
  301.  
  302.  
  303. // ---------------------------------------------------------------------------
  304. //        • CopyGWorldToScreen
  305. // ---------------------------------------------------------------------------
  306.  
  307. void
  308. COffscreenBehavior::CopyGWorldToScreen(
  309.     StGWorldLocker &        inRenderingLocker)
  310. {
  311.     CWindowRecord *        colorWindow;
  312.     colorWindow = mShadowWindow.GetMacWindow();
  313.  
  314.     mShadowWindow.UseWindowsPort();
  315.  
  316.     StColorState        colorSaver;
  317.     ::ForeColor(blackColor);
  318.     ::BackColor(whiteColor);
  319.  
  320.     ::StdBits(    reinterpret_cast<BitMap *>(*inRenderingLocker.GetPixMap()),
  321.                 &mGWorldRect,
  322.                 &mGWorldRect,
  323.                 srcCopy,
  324.                 NULL);
  325.     
  326.     MarkOffscreenUpToDate();
  327. }
  328.  
  329.  
  330. // ---------------------------------------------------------------------------
  331. //        • DetachBehavior
  332. // ---------------------------------------------------------------------------
  333.  
  334. void
  335. COffscreenBehavior::DetachBehavior(void)
  336. {
  337.     // Unhook our QD Proc overrides
  338.     if (mQDProcsOverridden)
  339.     {
  340.         // Restore the original QD Procs
  341.         mShadowWindow.GetMacWindow()->port.grafProcs = mOrigQDProcs;
  342.         mQDProcsOverridden = false;
  343.     }
  344.     
  345.     CWindowBehavior::DetachBehavior();
  346. }
  347.  
  348.  
  349. // ---------------------------------------------------------------------------
  350. //        • SetUpForQDOverride                        [static]
  351. // ---------------------------------------------------------------------------
  352.  
  353. COffscreenBehavior *
  354. COffscreenBehavior::SetUpForQDOverride(
  355.     CGrafPtr        inCurPort)
  356. {
  357.     // Start by looking up the related shadow window...
  358.     CWindowRecord *        currentWindow = reinterpret_cast<CWindowRecord *>(inCurPort);
  359.     CShadowWindow *        shadowWindow = COutOfContextApp::sOutOfContextApp->LookUpShadowWindow(currentWindow);
  360.  
  361.     ThrowIfNULL_(shadowWindow);
  362.  
  363.     COffscreenBehavior * behavior = static_cast<COffscreenBehavior *>(shadowWindow->GetBehavior());
  364.     
  365.     if (behavior != NULL && behavior->mGWorldsAllocated)
  366.     {
  367.         behavior->CopyPortParameters(reinterpret_cast<CGrafPtr>(currentWindow));
  368.         return behavior;
  369.     }
  370.     
  371.     return NULL;
  372. }
  373.  
  374.  
  375. // ---------------------------------------------------------------------------
  376. //        • CopyPixPatParam
  377. // ---------------------------------------------------------------------------
  378.  
  379. void
  380. COffscreenBehavior::CopyPixPatParam(
  381.     PixPatHandle *        inSrc,
  382.     PixPatHandle *        inDest)
  383. {
  384.     if (*inSrc == NULL)
  385.     {
  386.         if (*inDest != NULL)
  387.         {
  388.             ::DisposePixPat(*inDest);
  389.             *inDest = NULL;
  390.         }
  391.     }
  392.     else
  393.     {
  394.         if (*inDest == NULL)
  395.             *inDest = ::NewPixPat();
  396.  
  397.         if (*inDest != NULL)
  398.             ::CopyPixPat(*inSrc, *inDest);
  399.     }
  400. }
  401.  
  402.  
  403. // ---------------------------------------------------------------------------
  404. //        • CopyPortParameters
  405. // ---------------------------------------------------------------------------
  406.  
  407. void
  408. COffscreenBehavior::CopyPortParameters(
  409.     CGrafPtr    inCurPort)
  410. {
  411.     if (mAllocateBacking)
  412.     {
  413.         ::SetGWorld(mBackingGWorld, NULL);
  414.         
  415.         // We need to copy all the important parameters from 
  416.         // the specified port to the offscreen port.
  417.         ::SetClip(inCurPort->clipRgn);
  418.         //::CopyRgn(inCurPort->visRgn, mBackingGWorld->visRgn);
  419.         
  420.         // Make sure the origin is the same
  421.         mBackingGWorld->portRect = inCurPort->portRect;
  422.         
  423.         ::RGBForeColor(&inCurPort->rgbFgColor);
  424.         ::RGBBackColor(&inCurPort->rgbBkColor);
  425.         mBackingGWorld->pnLoc = inCurPort->pnLoc;
  426.         mBackingGWorld->pnMode = inCurPort->pnMode;
  427.         mBackingGWorld->pnVis = inCurPort->pnVis;
  428.         ::TextFont(inCurPort->txFont);
  429.         ::TextFace(inCurPort->txFace);
  430.         ::TextMode(inCurPort->txMode);
  431.         ::TextSize(inCurPort->txSize);
  432.         //mBackingGWorld->spExtra = inCurPort->spExtra;
  433.         //mBackingGWorld->fgColor = inCurPort->fgColor;
  434.         //mBackingGWorld->bkColor = inCurPort->bkColor;
  435.         //mBackingGWorld->colrBit = inCurPort->colrBit;
  436.         //mBackingGWorld->patStretch = inCurPort->patStretch;
  437.  
  438.         // Make a copy of the grafVars handle
  439.         if (mBackingGWorld->grafVars != NULL)
  440.         {
  441.             ::DisposeHandle(mBackingGWorld->grafVars);
  442.             mBackingGWorld->grafVars = NULL;
  443.         }
  444.         
  445.         mBackingGWorld->grafVars = inCurPort->grafVars;
  446.         ::HandToHand(&mBackingGWorld->grafVars);
  447.         ThrowIfNULL_(mBackingGWorld->grafVars);
  448.         
  449.         StHandleLocker        locker(mBackingGWorld->grafVars);
  450.         GrafVars *            grafVars = reinterpret_cast<GrafVars *>(*mBackingGWorld->grafVars);
  451.         
  452.         // Now we need to copy several of the handles hanging off of grafVars
  453.         if (grafVars->pmFgColor != NULL)
  454.             ::HandToHand(&grafVars->pmFgColor);
  455.  
  456.         if (grafVars->pmBkColor != NULL)
  457.             ::HandToHand(&grafVars->pmBkColor);
  458.         
  459.         CopyPixPatParam(&inCurPort->bkPixPat, &mBackingGWorld->bkPixPat);
  460.         CopyPixPatParam(&inCurPort->pnPixPat, &mBackingGWorld->pnPixPat);
  461.         CopyPixPatParam(&inCurPort->fillPixPat, &mBackingGWorld->fillPixPat);
  462.     }
  463. }
  464.  
  465.  
  466. // ---------------------------------------------------------------------------
  467. //        • InitOverrideQDProcs                            [static]
  468. // ---------------------------------------------------------------------------
  469.  
  470. void
  471. COffscreenBehavior::InitOverrideQDProcs(void)
  472. {
  473.     // Start with a complete copy of the original
  474.     ::SetStdCProcs(&sOverrideQDProcs);
  475.  
  476.     sOverrideQDProcs.lineProc        = NewQDLineProc(&COffscreenBehavior::OverrideQDLineProc);
  477.     sOverrideQDProcs.rectProc        = NewQDRectProc(&COffscreenBehavior::OverrideQDRectProc);
  478.     sOverrideQDProcs.rgnProc        = NewQDRgnProc(&COffscreenBehavior::OverrideQDRgnProc);
  479.     sOverrideQDProcs.bitsProc        = NewQDBitsProc(&COffscreenBehavior::OverrideQDBitsProc);
  480.     sOverrideQDProcs.textProc        = NewQDTextProc(&COffscreenBehavior::OverrideQDTextProc);
  481. //    sOverrideQDProcs.txMeasProc        = NewQDTxMeasProc(&COffscreenBehavior::OverrideQDTxMeasProc);
  482.  
  483.     sOverrideQDProcsInited = true;
  484. }
  485.  
  486.  
  487. #pragma mark -
  488. #pragma mark • Static QD Override Procs
  489.  
  490. // ---------------------------------------------------------------------------
  491. //        • OverrideQDTextProc                            [static]
  492. // ---------------------------------------------------------------------------
  493.  
  494. pascal void
  495. COffscreenBehavior::OverrideQDTextProc(
  496.     short         inByteCount, 
  497.     Ptr         inTextBuf, 
  498.     Point         inNumer, 
  499.     Point         inDenom)
  500. {
  501.     try
  502.     {
  503.         StCPortSaver        portSaver;
  504.         
  505.         COffscreenBehavior * behavior = SetUpForQDOverride(portSaver.GetSavedPort());
  506.         
  507.         if (behavior != NULL)
  508.             behavior->DoQDText(portSaver.GetSavedPort(), inByteCount, inTextBuf, inNumer, inDenom);
  509.     }
  510.     catch (...)
  511.     {
  512.         // Make sure we don't throw back into QD
  513.     }
  514. }
  515.  
  516.  
  517. // ---------------------------------------------------------------------------
  518. //        • OverrideQDLineProc                            [static]
  519. // ---------------------------------------------------------------------------
  520.  
  521. pascal void
  522. COffscreenBehavior::OverrideQDLineProc(
  523.     Point         inNewPt)
  524. {
  525.     try
  526.     {
  527.         StCPortSaver        portSaver;
  528.         
  529.         COffscreenBehavior * behavior = SetUpForQDOverride(portSaver.GetSavedPort());
  530.  
  531.         if (behavior != NULL)
  532.             behavior->DoQDLine(portSaver.GetSavedPort(), inNewPt);
  533.     }
  534.     catch (...)
  535.     {
  536.         // Make sure we don't throw back into QD
  537.     }
  538. }
  539.  
  540.  
  541. // ---------------------------------------------------------------------------
  542. //        • OverrideQDRectProc                            [static]
  543. // ---------------------------------------------------------------------------
  544.  
  545. pascal void
  546. COffscreenBehavior::OverrideQDRectProc(
  547.     GrafVerb         inVerb, 
  548.     Rect *            inRect)
  549. {
  550.     try
  551.     {
  552.         StCPortSaver        portSaver;
  553.         
  554.         COffscreenBehavior * behavior = SetUpForQDOverride(portSaver.GetSavedPort());
  555.  
  556.         if (behavior != NULL)
  557.             behavior->DoQDRect(portSaver.GetSavedPort(), inVerb, inRect);
  558.     }
  559.     catch (...)
  560.     {
  561.         // Make sure we don't throw back into QD
  562.     }
  563. }
  564.  
  565.  
  566. // ---------------------------------------------------------------------------
  567. //        • OverrideQDRgnProc                            [static]
  568. // ---------------------------------------------------------------------------
  569.  
  570. pascal void
  571. COffscreenBehavior::OverrideQDRgnProc(
  572.     GrafVerb         inVerb, 
  573.     RgnHandle         inRgn)
  574. {
  575.     try
  576.     {
  577.         StCPortSaver        portSaver;
  578.         
  579.         COffscreenBehavior * behavior = SetUpForQDOverride(portSaver.GetSavedPort());
  580.  
  581.         if (behavior != NULL)
  582.             behavior->DoQDRgn(portSaver.GetSavedPort(), inVerb, inRgn);
  583.     }
  584.     catch (...)
  585.     {
  586.         // Make sure we don't throw back into QD
  587.     }
  588. }
  589.  
  590.  
  591. // ---------------------------------------------------------------------------
  592. //        • OverrideQDBitsProc                        [static]
  593. // ---------------------------------------------------------------------------
  594.  
  595. pascal void
  596. COffscreenBehavior::OverrideQDBitsProc(
  597.     BitMap *        inSrcBits, 
  598.     Rect *            inSrcRect, 
  599.     Rect *            inDstRect, 
  600.     short             inMode, 
  601.     RgnHandle         inMaskRgn)
  602. {
  603.     try
  604.     {
  605.         StCPortSaver        portSaver;
  606.         
  607.         COffscreenBehavior * behavior = SetUpForQDOverride(portSaver.GetSavedPort());
  608.  
  609.         if (behavior != NULL)
  610.         {
  611.             CGrafPtr            origPort;
  612.             origPort = portSaver.GetSavedPort();
  613.             
  614.             // Are they copying from the screen itself?
  615.             if (inSrcBits->baseAddr == ::LMGetScrnBase() &&
  616.                 behavior->mAllocateBacking)
  617.             {
  618.                 behavior->DoQDBits(behavior->mBackingGWorld, 
  619.                         inSrcBits, inSrcRect, inDstRect, inMode, inMaskRgn);
  620.             }
  621.             else
  622.             {
  623.                 behavior->DoQDBits(portSaver.GetSavedPort(), inSrcBits, 
  624.                         inSrcRect, inDstRect, inMode, inMaskRgn);
  625.             }
  626.         }
  627.     }
  628.     catch (...)
  629.     {
  630.         // Make sure we don't throw back into QD
  631.     }
  632. }
  633.  
  634.  
  635. // ---------------------------------------------------------------------------
  636. //        • OverrideQDTxMeasProc                        [static]
  637. // ---------------------------------------------------------------------------
  638.  
  639. pascal SInt16
  640. COffscreenBehavior::OverrideQDTxMeasProc(
  641.     SInt16             inByteCount, 
  642.     Ptr             inTextAddr, 
  643.     Point *            inNumer, 
  644.     Point *            inDenom, 
  645.     FontInfo *        inInfo)
  646. {
  647.     SInt16            textWidth = 0;
  648.     
  649.     try
  650.     {
  651.         StCPortSaver        portSaver;
  652.         
  653.         COffscreenBehavior * behavior = SetUpForQDOverride(portSaver.GetSavedPort());
  654.  
  655.         if (behavior != NULL)
  656.             textWidth = behavior->DoQDTxMeas(portSaver.GetSavedPort(), inByteCount, inTextAddr, inNumer, inDenom, inInfo);
  657.     }
  658.     catch (...)
  659.     {
  660.         // Make sure we don't throw back into QD
  661.     }
  662.  
  663.     return textWidth;
  664. }
  665.  
  666.  
  667. #pragma mark -
  668. #pragma mark • Virtual QD Procs
  669.  
  670. // ---------------------------------------------------------------------------
  671. //        • DoQDBits
  672. // ---------------------------------------------------------------------------
  673.  
  674. void
  675. COffscreenBehavior::DoQDBits(
  676.     CGrafPtr        inOrigPort,
  677.     BitMap *        inSrcBits, 
  678.     Rect *            inSrcRect, 
  679.     Rect *            inDstRect, 
  680.     short             inMode, 
  681.     RgnHandle         inMaskRgn)
  682. {
  683.     #pragma unused (inOrigPort)
  684.     
  685.     if (mAllocateBacking)
  686.     {
  687.         if (mFinderOffscreen == NULL)
  688.         {
  689.             // WARNING: This is a big, scary assumption. We are assuming that
  690.             // the source bits is a pix map handle.
  691.             mFinderOffscreen = reinterpret_cast<PixMapHandle>(inSrcBits);
  692.         }
  693.             
  694.         StGWorldLocker        locker(mBackingGWorld);
  695.         ::StdBits(inSrcBits, inSrcRect, inDstRect, inMode, inMaskRgn);
  696.         MarkOffscreenChanged();
  697.  
  698. #if UPDATE_WHEN_TRACKING
  699.         // If we're currently tracking, update immediately
  700.         if (::Button())
  701.             COutOfContextApp::sOutOfContextApp->GiveShadowWindowsTime(false);
  702. #endif
  703.     }
  704. }
  705.  
  706.  
  707. // ---------------------------------------------------------------------------
  708. //        • DoQDRect
  709. // ---------------------------------------------------------------------------
  710.  
  711. void
  712. COffscreenBehavior::DoQDRect(
  713.     CGrafPtr        inOrigPort,
  714.     GrafVerb        inVerb, 
  715.     Rect *            inRect)
  716. {
  717.     #pragma unused (inOrigPort)
  718.     
  719.     if (mAllocateBacking)
  720.     {
  721.         StGWorldLocker        locker(mBackingGWorld);
  722.         ::StdRect(inVerb, inRect);
  723.         MarkOffscreenChanged();
  724.  
  725. #if UPDATE_WHEN_TRACKING
  726.         // If we're currently tracking, update immediately
  727.         if (::Button())
  728.             COutOfContextApp::sOutOfContextApp->GiveShadowWindowsTime(false);
  729. #endif
  730.     }
  731. }
  732.  
  733.  
  734. // ---------------------------------------------------------------------------
  735. //        • DoQDRgn
  736. // ---------------------------------------------------------------------------
  737.  
  738. void
  739. COffscreenBehavior::DoQDRgn(
  740.     CGrafPtr        inOrigPort,
  741.     GrafVerb        inVerb, 
  742.     RgnHandle        inRgn)
  743. {
  744.     #pragma unused (inOrigPort)
  745.     
  746.     if (mAllocateBacking)
  747.     {
  748.         StGWorldLocker        locker(mBackingGWorld);
  749.         ::StdRgn(inVerb, inRgn);
  750.         MarkOffscreenChanged();
  751.  
  752. #if UPDATE_WHEN_TRACKING
  753.         // If we're currently tracking, update immediately
  754.         if (::Button())
  755.             COutOfContextApp::sOutOfContextApp->GiveShadowWindowsTime(false);
  756. #endif
  757.     }
  758. }
  759.  
  760.  
  761. // ---------------------------------------------------------------------------
  762. //        • DoQDLine
  763. // ---------------------------------------------------------------------------
  764.  
  765. void
  766. COffscreenBehavior::DoQDLine(
  767.     CGrafPtr        inOrigPort,
  768.     Point            inNewPt)
  769. {
  770.     if (mAllocateBacking)
  771.     {
  772.         StGWorldLocker        locker(mBackingGWorld);
  773.         ::StdLine(inNewPt);
  774.         
  775.         // Update the pen location
  776.         inOrigPort->pnLoc = inNewPt;
  777.         MarkOffscreenChanged();
  778.         
  779. #if UPDATE_WHEN_TRACKING
  780.         // If we're currently tracking, update immediately
  781.         if (::Button())
  782.             COutOfContextApp::sOutOfContextApp->GiveShadowWindowsTime(false);
  783. #endif
  784.     }
  785. }
  786.  
  787.  
  788. // ---------------------------------------------------------------------------
  789. //        • DoQDText
  790. // ---------------------------------------------------------------------------
  791.  
  792. void
  793. COffscreenBehavior::DoQDText(
  794.     CGrafPtr        inOrigPort,
  795.     short             inByteCount, 
  796.     Ptr             inTextBuf, 
  797.     Point             inNumer, 
  798.     Point             inDenom)
  799. {
  800.     if (mAllocateBacking)
  801.     {
  802.         StGWorldLocker        locker(mBackingGWorld);
  803.         ::StdText(inByteCount, inTextBuf, inNumer, inDenom);
  804.         
  805.         // Update the pen location
  806.         inOrigPort->pnLoc = mBackingGWorld->pnLoc;
  807.         MarkOffscreenChanged();
  808.         
  809. #if UPDATE_WHEN_TRACKING
  810.         // If we're currently tracking, update immediately
  811.         if (::Button())
  812.             COutOfContextApp::sOutOfContextApp->GiveShadowWindowsTime(false);
  813. #endif
  814.     }
  815. }
  816.  
  817.  
  818. // ---------------------------------------------------------------------------
  819. //        • DoQDTxMeas
  820. // ---------------------------------------------------------------------------
  821.  
  822. SInt16
  823. COffscreenBehavior::DoQDTxMeas(
  824.     CGrafPtr        inOrigPort,
  825.     SInt16             inByteCount, 
  826.     Ptr             inTextAddr, 
  827.     Point *            inNumer, 
  828.     Point *            inDenom, 
  829.     FontInfo *        inInfo)
  830. {
  831.     #pragma unused (inOrigPort)
  832.     
  833.     SInt16            textWidth = 0;
  834.     
  835.     if (mAllocateBacking)
  836.     {
  837.         StGWorldLocker        locker(mBackingGWorld);
  838.         
  839.         // Call through to the original
  840.         textWidth = CallQDTxMeasProc(mOrigQDProcs->txMeasProc, inByteCount, inTextAddr, inNumer, inDenom, inInfo);
  841.     }
  842.  
  843.     return textWidth;
  844. }
  845.  
  846.  
  847.  
  848.  
  849.  
  850.  
  851.